// JavaScript Document
//require MyClass.js
//clase para ordenar un array mediante el metodo QuickSort
MySortArray = new MyClass({
	CLASS_NAME: "MySortArray",	
	/**  
     * Property: array
	 * 	 Array a ordenar. Puede ser un array de objetos o de elementos simples 
     * {Array} 
     */
	array: new Array(), 	
	
	/**  
     * Property: method
	 * 	 Metodo de ordenacion a utilizar
     * {String} - Values: 'SORT', 'QUICKSORT'
     */
	method: 'QUICKSORT', 
	
	/**  
     * Property: property
	 * 	 En caso de que el array a ordenar sea de objetos debe especificarse la propiedad por la que se desea realizar el ordenamiento
     * {String}
     */	 
	property: null,
	
	/**  
     * Property: order
	 * 	 Orden a utilizar (ascendente/descendente)
     * {String} - Values: 'A', 'D'
     */
	order: 'A',
	
	init: function(array, metodo){
		this.array=array;
		if (metodo!=null)
			this.method=metodo.toUpperCase();
	},
	
	/** 
     * Method: _toUpper
     * 	 Pasa a uppercase un elemento recibido como parametro. Si el elemento no es del tipo string, lo retorna tal cual como lo recibio.
     * Parameters:
     *   element - {String | other} : Elemento a pasar upper case, solo si es String.
     */
	_toUpper: function(element) {
		var type = typeof element;
		if (type.toLowerCase()=='string')
			return element.toUpperCase();
		return element;
	},
	
	sortMethod: function(aod){
		var propiedad='';
		if (this.property!=null)
			propiedad='.'+this.property;
		var orden = (aod == "D")? 1 : -1;
		this.array.sort( new Function("x","y","return ( x"+propiedad+".toUpperCase() < y"+propiedad+".toUpperCase()) ? " + orden + " : ( x"+propiedad+".toUpperCase() > y"+propiedad+".toUpperCase() ) ? " + ( 0 - orden ) + " : 0;") );
	},
	
	quickSortMethod: function(aod){ //ascendente o descendente ("A"o"D")
		this.procesoQS(aod,0,this.array.length-1);
	},
	
	procesoQS: function(aod,ini,fin){
		var i = ini;
		var j = fin;
		var tmp;
		
		var c;
		if (this.property!=null)
		 	c = this._toUpper(this.array[Math.floor( ( i + j ) / 2 )][this.property]);
		else
			c =  this._toUpper(this.array[Math.floor( ( i + j ) / 2 )]);

		do {
			if ( aod == "A" ) { //ascendente
				if (this.property!=null){
					while ( ( i < fin ) && ( c > this._toUpper(this.array[i][this.property])) ) i++;
					while ( ( j > ini ) && ( c < this._toUpper(this.array[j][this.property])) ) j--;
				}
				else{
					while ( ( i < fin ) && ( c > this._toUpper(this.array[i])) ) i++;
					while ( ( j > ini ) && ( c < this._toUpper(this.array[j])) ) j--;
				}
			} else { //descendente
				if (this.property!=null){
					while ( ( i < fin ) && ( c < this._toUpper(this.array[i][this.property])) ) i++;
					while ( ( j > ini ) && ( c > this._toUpper(this.array[j][this.property])) ) j--;
				}
				else{
					while ( ( i < fin ) && ( c < this._toUpper(this.array[i])) ) i++;
					while ( ( j > ini ) && ( c > this._toUpper(this.array[j])) ) j--;
				}
			}
			if ( i < j ) {
				tmp = this.array[i];
				this.array[i] = this.array[j];
				this.array[j] = tmp;
			}
			if ( i <= j ) {
				i++;
				j--;
			}
		} while ( i <= j );

		if ( ini < j ) this.procesoQS(aod,ini,j);
		if ( i < fin ) this.procesoQS(aod,i,fin);
	},
	ordenar: function(aod, propiedad){		
		this.property = null;
		if (propiedad!=null)
			this.property = propiedad;			 
		if (this.array.length>1){
			if (this.method=="SORT") this.sortMethod(aod);
			if (this.method=="QUICKSORT") this.quickSortMethod(aod);
		}
	}
});